﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using BackgroundTest.Sprites;
using BackgroundTest.TestObjects;
using BackgroundTest.BasicAbstracts;
using BackgroundTest.ConsoleComponents;
using BackgroundTest.LogicInterface;

namespace BackgroundTest.BattleFieldManager
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class BattleField : Microsoft.Xna.Framework.DrawableGameComponent
    {
        ConsoleComponent console;

        SpriteBatch spriteBatch;

        SpriteManager spriteManager;

        LandformManager landformManager;

        SpriteFont spriteFont;

        Camera camera;

        MapTabular mapTabular;

        VectorMap clickon;

        int spritenumber;

        float zPrecision;
        
        public BattleField(BackGroundTest game)
            : base(game)
        {
            console = BackGroundTest.Console;
            BackgroundTest.BackGroundTest.Console.WriteLine();
            LuaFramework.Instance.registerLuaFunctions(this);
        }

        public void AssignMessage(SpriteMessage _spr)
        {
            spriteManager.AddMessage(_spr);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_assignNumber">the number of sprite</param>
        /// <param name="_direction">0=up;1=left;2=down;3=right</param>
        /// <param name="_moveType">0=walk;1=jump</param>
        /// <param name="_jumpheight">the height of jump</param>
        /// <param name="_isContinue"></param>
        [AttrLuaFunc("AssignSpriteMessage","Add message to sprite manager",
            "the number of sprite",
            "0=up;1=left;2=down;3=right",
            "0=walk;1=jump",
            "the height of jump",
            "is the message is processed simultaneously with the next")]
        public void AssignSpriteMessage(int _assignedNumber, int _direction, int _moveType, int _jumpHeight, int _isContinue)
        {
            Direction drcn;
            MoveType mvtyp;
            switch (_direction)
            {
                case 0:
                    drcn = Direction.Up;
                    break;
                case 1:
                    drcn = Direction.Left;
                    break;
                case 2:
                    drcn = Direction.Down;
                    break;
                case 3:
                    drcn = Direction.Right;
                    break;
                default:
                    drcn = Direction.Continue;
                    break;
            }
            switch (_moveType)
            {
                case 0:
                    mvtyp = MoveType.Walk;
                    spriteManager.AddMessage(new SpriteMessage(_assignedNumber, drcn, mvtyp, _isContinue == 1));
                    return;
                case 1:
                    mvtyp = MoveType.Jump;
                    spriteManager.AddMessage(new SpriteMessage(_assignedNumber, drcn, mvtyp, _jumpHeight, _isContinue == 1));
                    return;
                default:
                    mvtyp = MoveType.Continue;
                    break;
            }
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            camera = new Camera();

            clickon = new VectorMap(0, 0);
            spritenumber = 0;
            mapTabular = new MapTabular();

            landformManager = new LandformManager(camera);
            spriteManager = new SpriteManager(camera,0.03125f,mapTabular);

            console.WriteLine("@Battle Field>  Background initializing procedure succeeded.");

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
           
            landformManager.InitiateLandform(Game.Content.Load<Texture2D>(@"Background\grassland"),
                Game.Content.Load<Texture2D>(@"Background\sidemud"), mapTabular);
            zPrecision = landformManager.zPrecision;

            spriteManager.LoadContent(Game.Content.Load<Texture2D>(@"Charactor/walk"));

            spriteFont = Game.Content.Load<SpriteFont>(@"Fonts\Kootenay");

            base.LoadContent();
        }

       
        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            if (Mouse.GetState().RightButton == ButtonState.Pressed)
            {
                camera.MoveCamera(MouseTrack.Instance.MouseMovement);
            }

            if (KeyboardSense.Instance.IsKeyTriggerDown(Keys.Up))
            {
                spriteManager.AddMessage(new SpriteMessage(0, Direction.Up, MoveType.Walk));
            }

            if (KeyboardSense.Instance.IsKeyTriggerDown(Keys.Left))
            {
                spriteManager.AddMessage(new SpriteMessage(0, Direction.Left, MoveType.Walk));
            }

            if (KeyboardSense.Instance.IsKeyTriggerDown(Keys.Down))
            {
                spriteManager.AddMessage(new SpriteMessage(0, Direction.Down, MoveType.Walk));
            }

            if (KeyboardSense.Instance.IsKeyTriggerDown(Keys.Right))
            {
                spriteManager.AddMessage(new SpriteMessage(0, Direction.Right, MoveType.Walk));
            }

            spriteManager.Update(gameTime);

            landformManager.UpdateLandform(gameTime);

            clickon = landformManager.GetMouseMapPosition(MouseTrack.Instance.Position);

            spritenumber = spriteManager.GetMouseOnSprite(MouseTrack.Instance.Position);

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            // TODO: Add your drawing code here
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.None);

            spriteManager.Render(spriteBatch);

            landformManager.RenderLandform(spriteBatch);

            spriteBatch.DrawString(spriteFont, "The mouse is now on: (" + clickon.x + "," + clickon.y + ")", Vector2.Zero, Color.White);

            spriteBatch.DrawString(spriteFont, "The mouse is now on sprite " + spritenumber, new Vector2(0,25), Color.White);

            spriteBatch.DrawString(spriteFont, "Sprite's z-buffer = " + spriteManager.spriteList[0].zBuffer, new Vector2(0, 50), Color.White);

            //testObject.Render(spriteBatch);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}